package com.kornero.auto.util.data;

import com.kornero.auto.entities.Car;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.*;

public abstract class DataSource {

    private static final Logger logger = LoggerFactory.getLogger(DataSource.class);

    public static List<String> loadUrls() {
        final List<String> urls = FileManager.readFileLines("res/URLs.txt");
        if (logger.isTraceEnabled()) {
            for (final String url : urls) {
                logger.trace("loadUrls(): url = {}", url);
            }
        }
        return urls;
    }

    @SuppressWarnings("unchecked")
    public static Set<Car> loadCars() {
        final File file = new File("res/database.db");
        if (!file.exists()) {
            logger.warn("loadCars(): File not exists.");
            return new HashSet<>();
        }

        try (final ObjectInputStream objectInputStream =
                     new ObjectInputStream(new FileInputStream(file))) {
            final Object o = objectInputStream.readObject();
            if (o instanceof Set<?>) {
                return (Set<Car>) o; // Unchecked cast.
            }
        } catch (IOException | ClassNotFoundException e) {
            logger.error("loadCars():", e);
        }
        return new HashSet<>();
    }

    public static void saveCars(final Set<Car> cars) {
        final File file = new File("res/database.db");
        if (file.exists()) {
            final boolean delete = file.delete();
            logger.debug("saveCars(): delete = {}", delete);
        }

        try {
            final boolean create = file.createNewFile();
            logger.debug("saveCars(): create = {}", create);
        } catch (IOException e) {
            logger.error("saveCars(): ", e);
        }

        try (final ObjectOutputStream objectOutputStream =
                     new ObjectOutputStream(new FileOutputStream(file))) {
            objectOutputStream.writeObject(cars);
            objectOutputStream.flush();
        } catch (IOException e) {
            logger.error("saveCars():", e);
        }
    }

    public static Set<Car> sortCarsByDate(final Collection<Car> cars) {
        return new TreeSet<Car>(new CarsComparatorByDateInAscOrder()) {{
            addAll(cars);
        }};
    }

    public static class CarsComparatorByDateInAscOrder implements Comparator<Car>, Serializable {
        @Override
        public int compare(final Car car1, final Car car2) {
            if (car1 == null && car2 == null) {
                return 0;
            }
            if (car1 == null) {
                return 1;
            }
            if (car2 == null) {
                return -1;
            }
            if (car1.equals(car2)) {
                return 0;
            }
            return car1.getDate().compareTo(car2.getDate());
        }
    }
}
